<template>
	<div v-show="visible" class="my" style="position: fixed;z-index: 998;" :style="custyle" ref="elementRef">
		<!-- select -->
		<el-select v-if="types==='select'" :bind="attrs" v-model="selectAll" :loading="!options.length"
			@change="selectChange" @blur="onBlur" multiple ref="select" clearable>
			<el-option v-for="(item, key) in options" :key="key" :label="item?.label" :value="item?.value">
				<!--  -->
				<el-tag style="border: 0;" :color="item?.color" round effect="dark">
					{{ item?.label }}
				</el-tag>
				<!--  -->
			</el-option>
			<!--  -->
			<template #tag>
				<el-tag style="border: 0;" v-show="options[indexTo]?.value" :color="options[indexTo]?.color" round
					effect="dark">
					{{ options[indexTo]?.label }}
				</el-tag>
			</template>
			<template #loading>
				<el-icon class="is-loading">
					<svg class="circular" viewBox="0 0 20 20">
						<g class="path2 loading-path" stroke-width="0" style="animation: none; stroke: none">
							<circle r="3.375" class="dot1" rx="0" ry="0" />
							<circle r="3.375" class="dot2" rx="0" ry="0" />
							<circle r="3.375" class="dot4" rx="0" ry="0" />
							<circle r="3.375" class="dot3" rx="0" ry="0" />
						</g>
					</svg>
				</el-icon>
			</template>
		</el-select>
		<!-- select-icon -->
		<el-select v-if="types==='select-icon'" v-model="selectAll" :loading="!options.length" @change="selectChange"
			@blur="onBlur" multiple ref="select" clearable>
			<el-option v-for="(item,key) in options" :key="key" :label="item?.label" :value="item?.value">
				<div class="flex-align-center">
					<el-icon :color="item?.color">
						<component :is="item?.icon">
						</component>
					</el-icon>
					<el-text style="margin-left: 6px;">{{item?.label}}</el-text>
				</div>
			</el-option>
			<template #tag>
				<div class="flex-align-center" style="padding-left: 8px;">
					<el-icon :color="options[indexTo]?.color">
						<component :is="options[indexTo]?.icon">
						</component>
					</el-icon>
					<el-text size="small" style="margin-left: 6px;">{{options[indexTo]?.label}}</el-text>
				</div>
			</template>
			<template #loading>
				<el-icon class="is-loading">
					<svg class="circular" viewBox="0 0 20 20">
						<g class="path2 loading-path" stroke-width="0" style="animation: none; stroke: none">
							<circle r="3.375" class="dot1" rx="0" ry="0" />
							<circle r="3.375" class="dot2" rx="0" ry="0" />
							<circle r="3.375" class="dot4" rx="0" ry="0" />
							<circle r="3.375" class="dot3" rx="0" ry="0" />
						</g>
					</svg>
				</el-icon>
			</template>
		</el-select>
		<!-- number -->
		<el-input v-if="types==='number'" :bind="attrs" clearable  :max="999999999" v-model="inputValue"
			:type="types" ref="select" @input="onInput" @blur="onBlur"></el-input>
		<!-- text -->
		<el-input v-if="types==='text'" :bind="attrs" clearable maxlength="999999999999" v-model="inputValue"
			:type="types" ref="select" @input="onInput" @blur="onBlur"></el-input>
		<!-- date -->
		<el-date-picker v-if="types==='date'" :bind="attrs" style="width:100%;height: 40px;" v-model="inputValue"
			type="date" ref="select" @change="onInput" @blur="onBlur" />
	</div>
</template>
<script setup lang="ts">
	import { ref } from 'vue';
	import { findIndexByLabel, isEmpty } from '../../utils';
	import { getShipments } from '../../api/shipmentAPI';
	const emits = defineEmits(['blur', 'change']);
	const props = defineProps({
		/**
		 * 表单类型
		 */
		types: {
			type: String,
			default: ''
		},
		st_type: {
			type: String,
			default: ''
		},
		option: {
			type: Array,
			default: []
		},
		params: {
			default: ''
		},
		attrs: {
			type: Object,
			default: {}
		},
		/**
		 * 自定义样式
		 */
		style: {
			type: Object,
			default: ''
		},
		/**
		 * 
		 */
		element: {
			type: HTMLTableCellElement,
			default: null
		},
		/**
		 * 
		 */
		observerElement: {
			default: null
		},
		isp: {
			default: false
		}
	});
	interface ExtendedHTMLDivElement extends HTMLDivElement {
		/**
		 * 元素真实dom
		 */
		$el : any;
		/**
		 * 聚焦
		 */
		focus : () => void;
		/**
		 * 展开选择器下拉
		 */
		toggleMenu : () => void;
		handleOpen : () => void;
		handleClose : () => void;
	}
	//
	let observer : IntersectionObserver | null = null;
	//
	const elementRef = ref<ExtendedHTMLDivElement | null>(null);
	const select = ref<ExtendedHTMLDivElement | null>(null);
	const options = ref<Array<any>>([]);
	const indexTo = ref<number>(-1);
	const selectAll = ref<Array<any>>([]);
	const inputValue = ref<string | number>();
	const custyle = ref<any>(null);
	const visible = ref<boolean>(false);
	let timer = null;
	//获取元素信息
	const getElementInfo = () => {
		if (props.element === null) return;
		if (props.types === '') return;
		//
		selectAll.value = [props.params];
		console.log('props.params --->', props.params);
		inputValue.value = props.params;
		if (selectAll.value[0] !== '') {
			indexTo.value = findIndexByLabel(options.value, props.params, 'value');
		}
		let tops = 0;
		let lefts = 0;
		if (props.isp) {
			tops = 80;
			lefts = 240;
		}
		console.log('element.value --->', props.element);
		const { scrollWidth, scrollHeight } = props.element;
		// console.log('scrollWidth --->', scrollWidth);
		// console.log('scrollHeight --->', scrollHeight);
		// 获取元素的边界矩形
		const rect = props.element.getBoundingClientRect();
		console.log('rect --->', rect);
		// 获取当前页面的滚动偏移量
		const scrollTop = window.scrollY;
		const scrollLeft = window.scrollX;
		// console.log('window --->', window);
		// 计算元素相对于窗口的实际位置
		const top = rect.top + scrollTop;
		const left = rect.left + scrollLeft;
		//
		custyle.value = {
			width: scrollWidth + 'px',
			height: scrollHeight + 'px',
			left: (left - lefts) + 'px',
			top: (top - tops) + 'px',
		}
		console.log('select --->', select.value.$el);
		if (select.value.$el?.children && select.value.$el?.children.length > 0) {
			select.value.$el.children[0].style.height = scrollHeight + 'px';
		} else {
			select.value.$el.nextSibling.children[0].style.height = scrollHeight + 'px';
		}
		//
		if (elementRef.value) {
			observer = new IntersectionObserver((entries : IntersectionObserverEntry[]) => {
				entries.forEach(entry => {
					if (entry.intersectionRatio !== 1) {
						emits('blur');
					}
				}, {
					root: props.observerElement,
					threshold: 0.1, // 当至少 10% 的目标元素可见时触发回调
				});
			});
			observer.observe(elementRef.value);
		}
		setTimeout(() => {
			//聚焦
			if (select.value?.focus) {
				select.value.focus();
			}
			//如果是选择器就展开下拉
			if (select.value?.toggleMenu) {
				select.value.toggleMenu();
			}
			//如果是日期选择器
			if (props.types === 'date') {
				select.value.focus();
				select.value.handleOpen();
			}
		}, 1);
		//显示文本框
		visible.value = true;
		//清空定时器 防止触发上一次定时器 造成不必要的bug
		clearTimeout(timer);
		timer = null;
		//
		getgetShipment();
	}
	//
	const getgetShipment = async () => {
		options.value = [];
		let newOptions = [];
		//
		if (props.types === 'select-icon') {
			newOptions = props.option;
		} else {
			newOptions = await getShipments(props.st_type);
		}
		//
		options.value = [...newOptions];

		options.value.forEach((item : any, key : number) => {
			if (selectAll.value[0] === item.value) {
				indexTo.value = key;
			}
		});
	}
	//改变
	const selectChange = (value : Array<any>) => {
		// console.log('value --->', value);
		//
		let value1 = [value[value.length - 1]];
		if (isEmpty(value1[0])) {
			value1 = [];
		} else {
			value1 = [value1[0]];
		}
		selectAll.value = [];
		selectAll.value = value1;
		indexTo.value = findIndexByLabel(options.value, value1[0], 'value');
		//
		select.value.blur();
		//
		emits('change', value1[0]);
	}
	//文本框改变
	const onInput = (value : string | number) => {
		emits('change', value);
		if (props.types === 'date') {
			select.value.handleClose();
			onBlur();
		}
	}
	//失去焦点
	const onBlur = () => {
		//延长隐藏时间 防止页面上的某些bug
		timer = setTimeout(() => {
			visible.value = false;
			clearTimeout(timer);
			timer = null;
		}, 200);
		//
		emits('blur');
	}
	//
	defineExpose({
		getElementInfo
	});
</script>
<style>
	@import '../../assets/css/my-form-item.css';

	.el-select-dropdown__loading {
		display: flex;
		justify-content: center;
		align-items: center;
		height: 100px;
		font-size: 20px;
	}

	.circular {
		display: inline;
		height: 30px;
		width: 30px;
		animation: loading-rotate 2s linear infinite;
	}

	.path {
		animation: loading-dash 1.5s ease-in-out infinite;
		stroke-dasharray: 90, 150;
		stroke-dashoffset: 0;
		stroke-width: 2;
		stroke: var(--el-color-primary);
		stroke-linecap: round;
	}

	.loading-path .dot1 {
		transform: translate(3.75px, 3.75px);
		fill: var(--el-color-primary);
		animation: custom-spin-move 1s infinite linear alternate;
		opacity: 0.3;
	}

	.loading-path .dot2 {
		transform: translate(calc(100% - 3.75px), 3.75px);
		fill: var(--el-color-primary);
		animation: custom-spin-move 1s infinite linear alternate;
		opacity: 0.3;
		animation-delay: 0.4s;
	}

	.loading-path .dot3 {
		transform: translate(3.75px, calc(100% - 3.75px));
		fill: var(--el-color-primary);
		animation: custom-spin-move 1s infinite linear alternate;
		opacity: 0.3;
		animation-delay: 1.2s;
	}

	.loading-path .dot4 {
		transform: translate(calc(100% - 3.75px), calc(100% - 3.75px));
		fill: var(--el-color-primary);
		animation: custom-spin-move 1s infinite linear alternate;
		opacity: 0.3;
		animation-delay: 0.8s;
	}

	@keyframes loading-rotate {
		to {
			transform: rotate(360deg);
		}
	}

	@keyframes loading-dash {
		0% {
			stroke-dasharray: 1, 200;
			stroke-dashoffset: 0;
		}

		50% {
			stroke-dasharray: 90, 150;
			stroke-dashoffset: -40px;
		}

		100% {
			stroke-dasharray: 90, 150;
			stroke-dashoffset: -120px;
		}
	}

	@keyframes custom-spin-move {
		to {
			opacity: 1;
		}
	}
</style>
<style scoped lang="scss">
	@import '../../assets/css/index.scss';
</style>